1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.cache;
18
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.collect.ImmutableList;
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Sets;
24 import com.google.common.testing.FakeTicker;
25
26 import junit.framework.TestCase;
27
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32 import java.util.concurrent.Callable;
33 import java.util.concurrent.ConcurrentMap;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.TimeUnit;
36
37
38
39
40
41
42
43 @GwtCompatible
44 public class CacheBuilderGwtTest extends TestCase {
45
46 private FakeTicker fakeTicker;
47
48 @Override
49 protected void setUp() throws Exception {
50 super.setUp();
51
52 fakeTicker = new FakeTicker();
53 }
54
55 public void testLoader() throws ExecutionException {
56
57 final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
58 .build();
59
60 Callable<Integer> loader = new Callable<Integer>() {
61 private int i = 0;
62
63 @Override
64 public Integer call() throws Exception {
65 return ++i;
66 }
67 };
68
69 cache.put(0, 10);
70
71 assertEquals(Integer.valueOf(10), cache.get(0, loader));
72 assertEquals(Integer.valueOf(1), cache.get(20, loader));
73 assertEquals(Integer.valueOf(2), cache.get(34, loader));
74
75 cache.invalidate(0);
76 assertEquals(Integer.valueOf(3), cache.get(0, loader));
77
78 cache.put(0, 10);
79 cache.invalidateAll();
80 assertEquals(Integer.valueOf(4), cache.get(0, loader));
81 }
82
83 public void testSizeConstraint() {
84 final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
85 .maximumSize(4)
86 .build();
87
88 cache.put(1, 10);
89 cache.put(2, 20);
90 cache.put(3, 30);
91 cache.put(4, 40);
92 cache.put(5, 50);
93
94 assertEquals(null, cache.getIfPresent(10));
95
96 assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
97 assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
98 assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
99 assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
100
101 cache.put(1, 10);
102 assertEquals(Integer.valueOf(10), cache.getIfPresent(1));
103 assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
104 assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
105 assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
106 assertEquals(null, cache.getIfPresent(2));
107 }
108
109 public void testLoadingCache() throws ExecutionException {
110 CacheLoader<Integer, Integer> loader = new CacheLoader<Integer, Integer>() {
111 int i = 0;
112 @Override
113 public Integer load(Integer key) throws Exception {
114 return i++;
115 }
116
117 };
118
119 LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
120 .build(loader);
121
122 cache.put(10, 20);
123
124 Map<Integer, Integer> map = cache.getAll(ImmutableList.of(10, 20, 30, 54, 443, 1));
125
126 assertEquals(Integer.valueOf(20), map.get(10));
127 assertEquals(Integer.valueOf(0), map.get(20));
128 assertEquals(Integer.valueOf(1), map.get(30));
129 assertEquals(Integer.valueOf(2), map.get(54));
130 assertEquals(Integer.valueOf(3), map.get(443));
131 assertEquals(Integer.valueOf(4), map.get(1));
132 assertEquals(Integer.valueOf(5), cache.get(6));
133 assertEquals(Integer.valueOf(6), cache.apply(7));
134 }
135
136 public void testExpireAfterAccess() {
137 final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
138 .expireAfterAccess(1000, TimeUnit.MILLISECONDS)
139 .ticker(fakeTicker)
140 .build();
141
142 cache.put(0, 10);
143 cache.put(2, 30);
144
145 fakeTicker.advance(999, TimeUnit.MILLISECONDS);
146 assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
147 fakeTicker.advance(1, TimeUnit.MILLISECONDS);
148 assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
149 fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
150 assertEquals(null, cache.getIfPresent(0));
151 }
152
153 public void testExpireAfterWrite() {
154 final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
155 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
156 .ticker(fakeTicker)
157 .build();
158
159 cache.put(10, 100);
160 cache.put(20, 200);
161 cache.put(4, 2);
162
163 fakeTicker.advance(999, TimeUnit.MILLISECONDS);
164 assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
165 assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
166 assertEquals(Integer.valueOf(2), cache.getIfPresent(4));
167
168 fakeTicker.advance(2, TimeUnit.MILLISECONDS);
169 assertEquals(null, cache.getIfPresent(10));
170 assertEquals(null, cache.getIfPresent(20));
171 assertEquals(null, cache.getIfPresent(4));
172
173 cache.put(10, 20);
174 assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
175
176 fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
177 assertEquals(null, cache.getIfPresent(10));
178 }
179
180 public void testExpireAfterWriteAndAccess() {
181 final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
182 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
183 .expireAfterAccess(500, TimeUnit.MILLISECONDS)
184 .ticker(fakeTicker)
185 .build();
186
187 cache.put(10, 100);
188 cache.put(20, 200);
189 cache.put(4, 2);
190
191 fakeTicker.advance(499, TimeUnit.MILLISECONDS);
192 assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
193 assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
194
195 fakeTicker.advance(2, TimeUnit.MILLISECONDS);
196 assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
197 assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
198 assertEquals(null, cache.getIfPresent(4));
199
200 fakeTicker.advance(499, TimeUnit.MILLISECONDS);
201 assertEquals(null, cache.getIfPresent(10));
202 assertEquals(null, cache.getIfPresent(20));
203
204 cache.put(10, 20);
205 assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
206
207 fakeTicker.advance(500, TimeUnit.MILLISECONDS);
208 assertEquals(null, cache.getIfPresent(10));
209 }
210
211 public void testMapMethods() {
212 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
213 .build();
214
215 ConcurrentMap<Integer, Integer> asMap = cache.asMap();
216
217 cache.put(10, 100);
218 cache.put(2, 52);
219
220 asMap.replace(2, 79);
221 asMap.replace(3, 60);
222
223 assertEquals(null, cache.getIfPresent(3));
224 assertEquals(null, asMap.get(3));
225
226 assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
227 assertEquals(Integer.valueOf(79), asMap.get(2));
228
229 asMap.replace(10, 100, 50);
230 asMap.replace(2, 52, 99);
231
232 assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
233 assertEquals(Integer.valueOf(50), asMap.get(10));
234 assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
235 assertEquals(Integer.valueOf(79), asMap.get(2));
236
237 asMap.remove(10, 100);
238 asMap.remove(2, 79);
239
240 assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
241 assertEquals(Integer.valueOf(50), asMap.get(10));
242 assertEquals(null, cache.getIfPresent(2));
243 assertEquals(null, asMap.get(2));
244
245 asMap.putIfAbsent(2, 20);
246 asMap.putIfAbsent(10, 20);
247
248 assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
249 assertEquals(Integer.valueOf(20), asMap.get(2));
250 assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
251 assertEquals(Integer.valueOf(50), asMap.get(10));
252 }
253
254 public void testRemovalListener() {
255 final int[] stats = new int[4];
256
257 RemovalListener<Integer, Integer> countingListener = new RemovalListener<Integer, Integer>() {
258 @Override
259 public void onRemoval(RemovalNotification<Integer, Integer> notification) {
260 switch (notification.getCause()) {
261 case EXPIRED:
262 stats[0]++;
263 break;
264 case EXPLICIT:
265 stats[1]++;
266 break;
267 case REPLACED:
268 stats[2]++;
269 break;
270 case SIZE:
271 stats[3]++;
272 break;
273 default:
274 throw new IllegalStateException("No collected exceptions in GWT CacheBuilder.");
275 }
276 }
277 };
278
279 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
280 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
281 .removalListener(countingListener)
282 .ticker(fakeTicker)
283 .maximumSize(2)
284 .build();
285
286
287 cache.put(3, 20);
288 cache.put(6, 2);
289 cache.put(98, 45);
290 cache.put(56, 76);
291 cache.put(23, 84);
292
293
294 cache.put(23, 20);
295 cache.put(56, 49);
296 cache.put(23, 2);
297 cache.put(56, 4);
298
299
300 fakeTicker.advance(1001, TimeUnit.MILLISECONDS);
301
302 cache.getIfPresent(23);
303 cache.getIfPresent(56);
304
305
306 cache.put(1, 4);
307 cache.put(2, 8);
308
309 cache.invalidateAll();
310
311 assertEquals(2, stats[0]);
312 assertEquals(2, stats[1]);
313 assertEquals(4, stats[2]);
314 assertEquals(3, stats[3]);
315 }
316
317 public void testPutAll() {
318 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
319 .build();
320
321 cache.putAll(ImmutableMap.of(10, 20, 30, 50, 60, 90));
322
323 assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
324 assertEquals(Integer.valueOf(50), cache.getIfPresent(30));
325 assertEquals(Integer.valueOf(90), cache.getIfPresent(60));
326
327 cache.asMap().putAll(ImmutableMap.of(10, 50, 30, 20, 60, 70, 5, 5));
328
329 assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
330 assertEquals(Integer.valueOf(20), cache.getIfPresent(30));
331 assertEquals(Integer.valueOf(70), cache.getIfPresent(60));
332 assertEquals(Integer.valueOf(5), cache.getIfPresent(5));
333 }
334
335 public void testInvalidate() {
336 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
337 .build();
338
339 cache.put(654, 2675);
340 cache.put(2456, 56);
341 cache.put(2, 15);
342
343 cache.invalidate(654);
344
345 assertFalse(cache.asMap().containsKey(654));
346 assertTrue(cache.asMap().containsKey(2456));
347 assertTrue(cache.asMap().containsKey(2));
348 }
349
350 public void testInvalidateAll() {
351 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
352 .build();
353
354 cache.put(654, 2675);
355 cache.put(2456, 56);
356 cache.put(2, 15);
357
358 cache.invalidateAll();
359 assertFalse(cache.asMap().containsKey(654));
360 assertFalse(cache.asMap().containsKey(2456));
361 assertFalse(cache.asMap().containsKey(2));
362
363 cache.put(654, 2675);
364 cache.put(2456, 56);
365 cache.put(2, 15);
366 cache.put(1, 3);
367
368 cache.invalidateAll(ImmutableSet.of(1, 2));
369
370 assertFalse(cache.asMap().containsKey(1));
371 assertFalse(cache.asMap().containsKey(2));
372 assertTrue(cache.asMap().containsKey(654));
373 assertTrue(cache.asMap().containsKey(2456));
374 }
375
376 public void testAsMap_containsValue() {
377 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
378 .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
379 .ticker(fakeTicker)
380 .build();
381
382 cache.put(654, 2675);
383 fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
384 cache.put(2456, 56);
385 cache.put(2, 15);
386
387 fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
388
389 assertTrue(cache.asMap().containsValue(15));
390 assertTrue(cache.asMap().containsValue(56));
391 assertFalse(cache.asMap().containsValue(2675));
392 }
393
394 public void testAsMap_containsKey() {
395 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
396 .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
397 .ticker(fakeTicker)
398 .build();
399
400 cache.put(654, 2675);
401 fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
402 cache.put(2456, 56);
403 cache.put(2, 15);
404
405 fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
406
407 assertTrue(cache.asMap().containsKey(2));
408 assertTrue(cache.asMap().containsKey(2456));
409 assertFalse(cache.asMap().containsKey(654));
410 }
411
412 public void testAsMapValues_contains() {
413 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
414 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
415 .ticker(fakeTicker)
416 .build();
417
418 cache.put(10, 20);
419 fakeTicker.advance(500, TimeUnit.MILLISECONDS);
420 cache.put(20, 22);
421 cache.put(5, 10);
422
423 fakeTicker.advance(501, TimeUnit.MILLISECONDS);
424
425 assertTrue(cache.asMap().values().contains(22));
426 assertTrue(cache.asMap().values().contains(10));
427 assertFalse(cache.asMap().values().contains(20));
428 }
429
430 public void testAsMapKeySet() {
431 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
432 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
433 .ticker(fakeTicker)
434 .build();
435
436 cache.put(10, 20);
437 fakeTicker.advance(500, TimeUnit.MILLISECONDS);
438 cache.put(20, 22);
439 cache.put(5, 10);
440
441 fakeTicker.advance(501, TimeUnit.MILLISECONDS);
442
443 Set<Integer> foundKeys = Sets.newHashSet();
444 for (Integer current : cache.asMap().keySet()) {
445 foundKeys.add(current);
446 }
447
448 assertEquals(ImmutableSet.of(20, 5), foundKeys);
449 }
450
451
452 public void testAsMapKeySet_contains() {
453 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
454 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
455 .ticker(fakeTicker)
456 .build();
457
458 cache.put(10, 20);
459 fakeTicker.advance(500, TimeUnit.MILLISECONDS);
460 cache.put(20, 22);
461 cache.put(5, 10);
462
463 fakeTicker.advance(501, TimeUnit.MILLISECONDS);
464
465 assertTrue(cache.asMap().keySet().contains(20));
466 assertTrue(cache.asMap().keySet().contains(5));
467 assertFalse(cache.asMap().keySet().contains(10));
468 }
469
470 public void testAsMapEntrySet() {
471 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
472 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
473 .ticker(fakeTicker)
474 .build();
475
476 cache.put(10, 20);
477 fakeTicker.advance(500, TimeUnit.MILLISECONDS);
478 cache.put(20, 22);
479 cache.put(5, 10);
480
481 fakeTicker.advance(501, TimeUnit.MILLISECONDS);
482
483 int sum = 0;
484 for (Entry<Integer, Integer> current : cache.asMap().entrySet()) {
485 sum += current.getKey() + current.getValue();
486 }
487 assertEquals(57, sum);
488 }
489
490 public void testAsMapValues_iteratorRemove() {
491 Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
492 .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
493 .ticker(fakeTicker)
494 .build();
495
496 cache.put(10, 20);
497 Iterator<Integer> iterator = cache.asMap().values().iterator();
498 iterator.next();
499 iterator.remove();
500
501 assertEquals(0, cache.size());
502 }
503 }